﻿using System;
using System.Collections.Generic;
using System.Peppers.UI;
using System.Peppers.Win32;
using System.Text;
using System.Peppers.Wmi;
using System.Linq;
using System.Net;
using System.Management;

namespace System.Peppers.Testing
{
    public static class Program
    {
        private static void Main(string[] args)
        {
            try
            {
                //Host file test
                //RunHostFileTest();

                //Monitor Power test
                //RunMonitorPowerTest();

                //Screen Resolution Test
                //RunScreenTest();

                //Network adapter Test
                //RunNetworkAdapterTest();

                //Process Test
                //RunProcessTest();

                //Network Drive Test
                //RunNetworkDriveTest();

                //Windows Activation Test
                //RunActivationTest();

                //Shutdown test
                RunShutdownTest();
            }
            catch (Exception exc)
            {
                Console.WriteLine("Error: " + exc);
            }

            Console.WriteLine("Press any key to quit...");
            Console.ReadKey();
        }

        private static void RunShutdownTest()
        {
            Console.WriteLine("******************* Shutdown Test *******************");

            try
            {
                //This also works locally if you don't use Impersonator and 127.0.0.1
                using (Impersonator impersonator = new Impersonator("administrator", "yourPassword"))
                {
                    Shutdown.Initiate(new ShutdownParameters
                        {
                            MachineName = "192.168.134.62",
                            Message = "BOO YAH!",
                            Restart = true,
                            ForceCloseApps = false,
                            Timeout = 5 * 60,
                        });

                    System.Threading.Thread.Sleep(3000);

                    Shutdown.Abort("192.68.134.62");
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
            }
        }

        private static void RunHostFileTest()
        {
            Console.WriteLine("******************* Host File Test *******************");

            HostFile hostFile = new HostFile();

            try
            {
                hostFile.Load();

                foreach (HostFileEntry entry in hostFile.Entries)
	            {
                    if (entry.IsEntry)
                    {
                        Console.WriteLine(entry.IP + "\t" + entry.Hostname);
                    }
	            }

                //Add tribalfusion.com
                //This way we can block those ridiculous belly fat ads
                if (!hostFile.EntriesByHostname.ContainsKey("tribalfusion.com"))
                {
                    hostFile.Add("127.0.0.1", "tribalfusion.com");
                    hostFile.Save();
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
            }
        }

        private static void RunMonitorPowerTest()
        {
            Console.WriteLine("******************* Monitor Power Test *******************");

            try
            {
                MonitorPower.Off();

                Console.WriteLine("Monitor off, press key...");
                Console.ReadKey();

                MonitorPower.On();

                Console.WriteLine("Monitor on, press key...");
                Console.ReadKey();

                MonitorPower.Standby();

                Console.WriteLine("Monitor standby, press key...");
                Console.ReadKey();

                MonitorPower.On();
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
            }
        }

        private static void RunScreenTest()
        {
            Console.WriteLine("******************* Screen Resolution Test *******************");

            try
            {
                Screen[] allscreens = Screen.AllScreens;
                foreach (Screen screen in allscreens)
                {
                    Console.WriteLine("{0}\t({1},{2},{3},{4})", screen.DeviceName, screen.Bounds.X, screen.Bounds.Y, screen.Bounds.Width, screen.Bounds.Height);
                }
               
                //I have 2 screens on my computer, let's make them 800x600
                allscreens[0].SetBounds(new Rectangle(0, 0, 800, 600));
                allscreens[1].SetBounds(new Rectangle(800, 0, 800, 600));

                Console.WriteLine("Press a key to change your resolution back...");
                Console.ReadKey();

                allscreens[0].SetBounds(new Rectangle(0, 0, 1280, 1024));
                allscreens[1].SetBounds(new Rectangle(1280, 0, 1280, 1024));
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
            }
        }

        private static void RunNetworkAdapterTest()
        {
            Console.WriteLine("******************* Network Adapter Test *******************");

            try
            {
                NetworkAdapterConfiguration nic = null;
                foreach (NetworkAdapterConfiguration config in NetworkAdapterConfiguration.GetAdapters())
                {
                    IPAddress[] ips = config.IPAddresses ?? new IPAddress[0],
                        sbmks = config.SubnetMasks ?? new IPAddress[0],
                        dfgw = config.DefaultGateways ?? new IPAddress[0];

                    object ret = config.Description;
                    ret = config.DhcpEnabled;
                    ret = config.DhcpServer;
                    ret = config.DnsServers;
                    ret = config.IsEnabled;
                    ret = config.MacAddress;
                    ret = config.TcpipNetbiosOptions;

                    Console.WriteLine("{4} {0}: {1} {2} {3}", config.Description, ips.FirstOrDefault(), sbmks.FirstOrDefault(), dfgw.FirstOrDefault(), config.Index);

                    if (config.Description == "Intel(R) PRO/1000 PL Network Connection - Packet Scheduler Miniport")
                    {
                        nic = config;
                    }
                }

                //Setnew ip
                if (nic != null)
                {
                    NetworkAdapterResult result = nic.EnableStatic(
                        new IPAddress[] 
                        { 
                            IPAddress.Parse("192.168.1.101")
                        }, 
                        new IPAddress[] 
                        { 
                            IPAddress.Parse("255.255.255.0") 
                        });
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
            }
        }

        private static void RunProcessTest()
        {
            Console.WriteLine("******************* Process Test *******************");

            ProcessResult result;

            foreach (Process process in Process.GetProcesses())
            {
                //Console.WriteLine(string.Format("** {0} - {1} - {2} - {3} - {4} - {5} - {6}",
                //    process.Name,
                //    process.ProcessId,
                //    process.ExecutablePath,
                //    process.CommandLine,
                //    process.CreationDate,
                //    process.Priority,
                //    process.Description));

                if (process.Name == "notepad.exe")
                {
                    result = process.Terminate(0);
                    Console.WriteLine("terminated notepad: ", result.ToString());
                }
            }

            //Now let's restart my roommates pc!
            WmiRemoteParameters remoteParams = new WmiRemoteParameters
                {
                    Hostname = "192.168.1.21",
                    Username = "Daniel",
                    //Tough password
                    Password = "password",
                };

            uint processId = 0;
            result = Process.Create(remoteParams, "shutdown -r -f -t 0", out processId);

            Console.WriteLine(string.Format("Result of restart: {0} pid: {1}", result, processId));
        }

        private static void RunNetworkDriveTest()
        {
            Console.WriteLine("******************* Network Drive Test *******************");

            NetworkDrive networkDrive = new NetworkDrive();

            Console.WriteLine(networkDrive.GetUsername('h'));
            Console.WriteLine(networkDrive.GetNetworkPath('h'));

            foreach (NetworkDriveInfo info in networkDrive.EnumerateMappings())
            {
                Console.WriteLine(info.DriveLetter + ":\t" + info.RemotePath);
                Console.WriteLine(info.Provider + ":\t" + info.Comment);
            }
        }

        private static void RunActivationTest()
        {
            Console.WriteLine("******************* Windows Activation Test *******************");

            //Note that this test will not work on a dell, see the comments on WindowsProductActivation for details
            //Dell or other OEM installations, set the product key from the BIOS so their customers do not have to deal 
            //with activation. Kind of nice, except if you want to change your key.

            //If you have a dell, at least you can get your key and print it out
            foreach (WindowsProductActivation activation in WindowsProductActivation.GetActivation())
            {
                ManagementStatus status;

                if (activation.ActivationRequired)
                {
                    //put a real key here
                    const string key = "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX";

                    status = activation.SetProductKey(key.Replace("-", string.Empty));
                    activation.Refresh();
                }

                string productKey = activation.GetProductKey();

                Console.WriteLine("Key: " + productKey);
                Console.WriteLine("Deactivating...");

                activation.Deactivate();
                activation.Refresh();

                Console.WriteLine("Activated: " + activation.ActivationRequired);

                Console.WriteLine("Reactivating...");
                status = activation.SetProductKey(productKey.Replace("-", string.Empty));

                Console.WriteLine("DONE!");

                //Should only be 1 instance
                break;
            }
        }
    }
}
